/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  							 script_has_artifact.h

	$Header: /heroes4/script_has_artifact.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( SCRIPT_HAS_ARTIFACT_H_INCLUDED )
#define SCRIPT_HAS_ARTIFACT_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <cassert>

#include "abstract_script_expression.h"
#include "artifact.h"
#include "script_expression_type.h"
#include "script_target_type.h"

class t_creature_stack;
class t_hero;
class t_player;

// --------------------------------------------------------------------------
// t_script_has_artifact class
// --------------------------------------------------------------------------

class t_script_has_artifact : public t_abstract_script_boolean_expression
{
public:
	// Types
	typedef t_script_player_target	t_player_target;
	typedef t_script_stack_target	t_stack_target;

	// Constructor
	t_script_has_artifact();

	// Member functions
	virtual t_result	evaluate(t_expression_context_hero const& context) const;
	virtual t_result	evaluate(t_expression_context_town const& context) const;
	virtual t_result	evaluate(t_expression_context_object const& context) const;
	virtual t_result	evaluate(t_expression_context_army const& context) const;
	virtual t_result	evaluate(t_expression_context_global const& context) const;

	t_player_target		get_player_target() const;
	t_stack_target		get_stack_target() const;
	virtual bool		read(
							std::streambuf &	stream,
							int					version );
	virtual bool		read_from_map(
							std::streambuf &	stream,
							int					format_version );
	bool				target_is_player() const;
	virtual bool		write( std::streambuf & stream ) const;

private:
	// Data members
	bool				m_target_is_player;
	union
	{
		t_player_target	player;
		t_stack_target	stack;
	}					m_target;
	t_artifact			m_artifact;

	virtual t_result	do_evaluate(t_creature_stack const* stack) const;
	virtual t_result	do_evaluate(t_creature_array const* array) const;
	virtual t_result	do_evaluate(t_player const* player) const;
};

// --------------------------------------------------------------------------
// t_script_has_artifact inline members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_script_has_artifact::t_script_has_artifact()
	:	m_target_is_player( false )
{
	m_target.stack = t_stack_target( 0 );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_script_has_artifact::t_player_target
t_script_has_artifact::get_player_target() const
{
	assert( m_target_is_player );
	return m_target.player;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_script_has_artifact::t_stack_target
t_script_has_artifact::get_stack_target() const
{
	assert( !m_target_is_player );
	return m_target.stack;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline bool t_script_has_artifact::target_is_player() const
{
	return m_target_is_player;
}

SPECIALIZE_SCRIPT_BOOLEAN_EXPRESSION( k_script_boolean_has_artifact, t_script_has_artifact );

#endif // !defined( SCRIPT_HAS_ARTIFACT_H_INCLUDED )
